Emberveil sourcegame/2006Scape Server/src/main/java/com/rs2/game/content/quests/impl/MemberQuests.java
package com.rs2.game.content.quests.impl;
import com.rs2.Constants;
import com.rs2.game.content.quests.QuestAssistant;
import com.rs2.game.content.quests.QuestRewards;
import com.rs2.game.players.Player;
import com.rs2.world.clip.Region;
/** Classic novice members' quests, with newly authored dialogue. World-thread only. */
public final class MemberQuests {
private MemberQuests() {}
private static final int DRUID_OPTIONS = 17400, JUNGLE_OPTIONS = 17401;
private static final int DRUID_CONTINUE = 17410, JUNGLE_CONTINUE = 17411;
private static final int[] RAW_MEAT = {2132, 2134, 2136, 2138};
private static final int[] ENCHANTED_MEAT = {522, 523, 524, 525};
private static final int[] HERB_OBJECTS = {2575, 2577, 2579, 2581, 2583};
private static final int[] HERBS = {1525, 1527, 1529, 1531, 1533};
private static final String[] HERB_NAMES = {"Snake weed", "Ardrigal", "Sito foil", "Volencia moss", "Rogue's purse"};
private static final String[] HERB_HINTS = {
"Search marshy jungle vines south-west of Tai Bwo Wannai.",
"Search the palm tree on the coast north-east of the village.",
"Search scorched earth around the fires south of the village.",
"Search the rocks in the mine south-east of the village.",
"Search a fungus-covered wall inside the northern Jogre cave."
};
private static boolean available(Player p) {
return !p.disconnected && !p.isDead && p.tutorialProgress >= 36
&& !p.stopPlayerPacket && !p.inTrade && !p.inDuel && p.duelStatus == 0 && !p.isBanking && !p.isShopping;
}
private static boolean near(Player p, int x, int y, int z, int radius) {
return p.heightLevel == z && Math.abs(p.absX - x) <= radius && Math.abs(p.absY - y) <= radius;
}
private static void chat(Player p, int npc, String name, String a, String b) {
p.nextChat = 0; p.dialogueAction = 0; p.talkingNpc = npc;
p.getDialogueHandler().sendNpcChat2(a, b, npc, name);
}
private static void update(Player p) { QuestAssistant.sendStages(p); }
public static boolean npc(Player p, int npc) {
if (npc != 455 && npc != 454 && npc != 740) return false;
if (!available(p)) return true;
if (npc == 455) {
if (!near(p, 2925, 3486, 0, 8)) return true;
switch (p.druidicRitual) {
case 0:
chat(p, npc, "Kaqemeex", "Our druids hope to restore the stone circle of Varrock.", "Will you help Sanfew prepare a ritual for Guthix?");
p.nextChat = DRUID_CONTINUE; break;
case 1: case 2:
chat(p, npc, "Kaqemeex", "Sanfew is upstairs in the herb shop in Taverley.", "He will explain which ingredients our ritual needs."); break;
case 3:
p.druidicRitual = 4; p.questPoints += 4;
p.getPlayerAssistant().addSkillXP(250, Constants.HERBLORE);
QuestRewards.questReward(p, "Druidic Ritual", "4 Quest Points", "250 base Herblore XP", "Emberveil's XP rate applies", "", "", "", 249);
p.nextChat = p.dialogueAction = 0; break;
default:
chat(p, npc, "Kaqemeex", "Your help with the ritual will not be forgotten.", "May Guthix guide your studies of Herblore."); break;
}
} else if (npc == 454) {
if (!near(p, 2896, 3428, 1, 5)) return true;
if (p.druidicRitual == 1) {
p.druidicRitual = 2; update(p);
chat(p, npc, "Sanfew", "Dip raw beef, rat meat, bear meat and chicken in", "the Cauldron of Thunder in Taverley Dungeon. Bring all four back.");
} else if (p.druidicRitual == 2) {
for (int meat : ENCHANTED_MEAT) if (!p.getItemAssistant().playerHasItem(meat, 1)) {
chat(p, npc, "Sanfew", "I need all four enchanted meats together.", "Your quest journal lists the ingredients and the cauldron."); return true;
}
for (int meat : ENCHANTED_MEAT) p.getItemAssistant().deleteItem(meat, 1);
p.druidicRitual = 3; update(p);
chat(p, npc, "Sanfew", "These are exactly what the ritual needs. Thank you!", "Return to Kaqemeex at the stone circle for your reward.");
} else {
chat(p, npc, "Sanfew", "Kaqemeex tends the stone circle north of Taverley.", "Speak with him about the druids' ritual.");
}
} else {
if (!near(p, 2809, 3086, 0, 6)) return true;
if (p.junglePotion == 0) {
if (p.druidicRitual != 4) {
chat(p, npc, "Trufitus", "I need an adventurer who understands druidic herbs.", "Complete Druidic Ritual before helping with my potion.");
} else {
chat(p, npc, "Trufitus", "I seek five herbs to commune with the gods of the jungle.", "Will you gather and identify them for me?"); p.nextChat = JUNGLE_CONTINUE;
}
} else if (p.junglePotion >= 1 && p.junglePotion <= 5) {
int i = p.junglePotion - 1;
if ((p.jungleHerbsFound & (1 << i)) != 0 && p.getItemAssistant().playerHasItem(HERBS[i] + 1, 1)) {
p.getItemAssistant().deleteItem(HERBS[i] + 1, 1);
p.junglePotion++;
if (p.junglePotion == 6) {
p.questPoints++;
p.getPlayerAssistant().addSkillXP(775, Constants.HERBLORE);
QuestRewards.questReward(p, "Jungle Potion", "1 Quest Point", "775 base Herblore XP", "Emberveil's XP rate applies", "", "", "", 1534);
p.nextChat = p.dialogueAction = 0;
} else {
update(p); chat(p, npc, "Trufitus", "Thank you. Next I need " + HERB_NAMES[i + 1] + ".", HERB_HINTS[i + 1]);
}
} else {
chat(p, npc, "Trufitus", "I still need " + HERB_NAMES[i] + ". Identify it before returning.", HERB_HINTS[i]);
}
} else chat(p, npc, "Trufitus", "The potion is ready, thanks to your courage and patience.", "The jungle has much to teach those who listen.");
}
return true;
}
public static boolean dialogue(Player p, int id) {
if (id != DRUID_CONTINUE && id != JUNGLE_CONTINUE) return false;
boolean druid = id == DRUID_CONTINUE;
if (!available(p) || !(druid ? near(p,2925,3486,0,8) && p.druidicRitual == 0
: near(p,2809,3086,0,6) && p.junglePotion == 0 && p.druidicRitual == 4)) {
p.nextChat = p.dialogueAction = 0; p.getPacketSender().closeAllWindows(); return true;
}
p.nextChat = 0; p.dialogueAction = druid ? DRUID_OPTIONS : JUNGLE_OPTIONS;
p.getDialogueHandler().sendOption("I'll help you.", "Not right now.");
return true;
}
public static boolean option(Player p, int button) {
int action = p.dialogueAction;
if (action != DRUID_OPTIONS && action != JUNGLE_OPTIONS) return false;
if (button != 9157 && button != 9158) return true;
boolean allowed = available(p);
p.dialogueAction = p.nextChat = 0; p.getPacketSender().closeAllWindows();
if (button != 9157 || !allowed) return true;
if (action == DRUID_OPTIONS && near(p,2925,3486,0,8) && p.druidicRitual == 0) {
p.druidicRitual = 1; update(p);
chat(p,455,"Kaqemeex","Thank you. Speak to Sanfew upstairs in the herb shop.","The shop is south of here, in Taverley.");
} else if (action == JUNGLE_OPTIONS && near(p,2809,3086,0,6) && p.druidicRitual == 4 && p.junglePotion == 0) {
p.junglePotion = 1; update(p);
chat(p,740,"Trufitus","First bring me Snake weed. Clean each herb you find.",HERB_HINTS[0]);
}
return true;
}
public static boolean useItem(Player p, int object, int x, int y, int item) {
if (object != 2142) return false;
if (!available(p) || !validObject(p,object,x,y)) return true;
if (p.druidicRitual != 2) { p.getPacketSender().sendMessage("Speak to Sanfew about the ritual ingredients first."); return true; }
for (int i = 0; i < RAW_MEAT.length; i++) if (item == RAW_MEAT[i]) {
if (p.getItemAssistant().playerHasItem(item,1)) {
// Replace the exact inventory slot: full backpacks are safe and no item can be lost.
int slot = p.getItemAssistant().getItemSlot(item);
if (p.playerItemsN[slot] != 1) {
p.getPacketSender().sendMessage("Separate the meat into individual inventory slots first.");
return true;
}
p.playerItems[slot] = ENCHANTED_MEAT[i] + 1;
com.rs2.game.items.Weight.updateWeight(p);
p.getItemAssistant().resetItems(3214); p.startAnimation(827);
p.getPacketSender().sendMessage("You dip the meat into the cauldron. It becomes enchanted.");
}
return true;
}
p.getPacketSender().sendMessage("The ritual requires raw beef, rat meat, bear meat and chicken.");
return true;
}
private static boolean validObject(Player p, int id, int x, int y) {
return near(p,x,y,p.heightLevel,2) && Region.objectExists(id,x,y,p.heightLevel);
}
public static boolean object(Player p, int id, int x, int y) {
int herb = -1;
for (int i = 0; i < HERB_OBJECTS.length; i++) if (id == HERB_OBJECTS[i]) herb = i;
boolean entrance = id == 2584 && x == 2824 && y == 3118;
boolean exit = id == 2585 && x == 2830 && y == 9522;
boolean gate = (id == 1557 || id == 1558) && (x == 2897 || x == 2898) && (y == 9831 || y == 9832) && p.heightLevel == 0;
if (herb == -1 && !entrance && !exit && !gate && id != 2142) return false;
if (!available(p) || !validObject(p,id,x,y)) return true;
p.clickObjectType = 0;
if (gate) {
// The legacy gate renderer leaves the closed collision behind. Limit the
// passage to this verified doorway rather than clearing surrounding walls.
p.objectX=x; p.objectY=y;
if(p.getGateHandler().gateStatus!=p.getGateHandler().OPEN) p.getDoubleGates().useDoubleGate(p,id);
p.stopMovement();p.getPlayerAssistant().movePlayer(p.absX>=2898 ? 2896 : 2899,9831,0);
p.getPacketSender().sendMessage("You pass through the cauldron chamber's gate.");
} else if (entrance || exit) {
p.startAnimation(828); p.stopMovement();
p.getPlayerAssistant().movePlayer(entrance ? 2831 : 2823, entrance ? 9521 : 3118, 0);
p.getPacketSender().sendMessage(entrance ? "You climb down into the Jogre cave." : "You climb out of the cave.");
} else if (id == 2142) {
p.getPacketSender().sendMessage("Use each of the four raw meats on the Cauldron of Thunder.");
} else {
if (p.junglePotion != herb + 1) { p.getPacketSender().sendMessage("Trufitus has not asked you to collect this herb."); return true; }
if (p.getItemAssistant().playerHasItem(HERBS[herb]) || p.getItemAssistant().playerHasItem(HERBS[herb]+1)) {
p.getPacketSender().sendMessage("You already have this herb. Identify it and return to Trufitus."); return true;
}
if (p.getItemAssistant().freeSlots() == 0) { p.getPacketSender().sendMessage("You need an empty inventory slot for the herb."); return true; }
if (p.getItemAssistant().addItem(HERBS[herb],1)) {
p.jungleHerbsFound |= 1 << herb; p.startAnimation(827);
p.getPacketSender().sendMessage("You find an unfamiliar herb. Click it to identify it.");
}
}
return true;
}
public static boolean clean(Player p, int item, int slot) {
for (int i = 0; i < HERBS.length; i++) if (item == HERBS[i]) {
if (!available(p) || slot < 0 || slot >= p.playerItems.length || p.playerItems[slot] != item+1 || p.playerItemsN[slot] != 1) return true;
if (p.playerLevel[Constants.HERBLORE] < 3) { p.getPacketSender().sendMessage("You need level 3 Herblore to identify this herb."); return true; }
p.playerItems[slot] = item+2;
com.rs2.game.items.Weight.updateWeight(p);
p.getItemAssistant().resetItems(3214);
p.getPlayerAssistant().addSkillXP(2.5,Constants.HERBLORE);
p.getPacketSender().sendMessage("You identify the herb as " + HERB_NAMES[i] + ".");
return true;
}
return false;
}
public static void journal(Player p, boolean druid) {
for (int i=8144;i<8196;i++) p.getPacketSender().sendString("",i);
String[] lines;
if (druid) {
switch(p.druidicRitual) {
case 0: lines=new String[]{"Speak to Kaqemeex at the stone circle north of Taverley.","No skill requirements. Beware of monsters in the dungeon."}; break;
case 1: lines=new String[]{"Speak to Sanfew upstairs in Taverley's herb shop."}; break;
case 2: lines=new String[]{"Take raw beef, raw rat meat, raw bear meat and raw chicken", "to the Cauldron of Thunder in Taverley Dungeon.","Enter by the ladder south of Taverley and head north.","Use each raw meat on the cauldron, then return all four", "enchanted meats to Sanfew upstairs in the herb shop."}; break;
case 3: lines=new String[]{"Sanfew has all four ingredients.","Return to Kaqemeex at the stone circle for your reward."}; break;
default: lines=new String[]{"@gre@Quest complete!","I helped prepare the druids' ritual for Guthix.","Reward: 4 Quest Points and 250 base Herblore XP.","Emberveil's configured XP rate applies."}; break;
}
} else if(p.junglePotion == 0) {
lines=new String[]{"Speak to Trufitus in Tai Bwo Wannai on Karamja.","Complete Druidic Ritual first. Level 3 Herblore is needed", "to identify the herbs. Bring food and antipoison."};
} else if(p.junglePotion <= 5) {
int i=p.junglePotion-1;
lines=new String[]{"Trufitus needs " + HERB_NAMES[i] + ".", HERB_HINTS[i], "Click the herb in your inventory to identify it.","Return each identified herb before gathering the next one.","The northern cave entrance is among rocks on the coast.","Use the hand holds inside the cave to climb back out."};
} else lines=new String[]{"@gre@Quest complete!","I gathered five herbs for Trufitus's potion.","Reward: 1 Quest Point and 775 base Herblore XP.","Emberveil's configured XP rate applies."};
p.getPacketSender().sendString(druid ? "Druidic Ritual" : "Jungle Potion",8144);
for(int i=0;i<lines.length;i++)p.getPacketSender().sendString(lines[i],8147+i);
p.getPacketSender().showInterface(8134);
}
}